/**
 * \file vmfile.h
 * \brief Operations on a VM binary file. All locations of things in a file
 * are given as a reference from the beginning of the file.
 **/

#ifndef R_VMFILE_H
#define R_VMFILE_H

/**
 * \brief The file header structure.
 **/
struct RFileHeaderT {
  char signature[8]; /*< This should always be RipeVM\0\0 */
  uint16_t ver_major;
  uint16_t ver_minor;
  uint32_t ext_header_size; /*< Size of the extra header. */
};
typedef struct RFileHeaderT RFileHeader;

/**
 * \brief The extra header.
 **/
struct RExtraHeaderT {
  uint32_t section_header_size; /*< Size of RSectionHeader */
  uint32_t num_sections; /*< Number of sections in the list */
  uint32_t p_sections; /*< Location of section table. */
};
typedef struct RExtraHeaderT RExtraHeader;

/**
 * \brief A section header.
 **/
struct RSectionHeaderT {
  uint32_t p_name; /*< Name of the section. */
  uint32_t flags; /*< Combination of section flags. */
  uint32_t size; /*< Size of the section (in bytes). */
  uint32_t p_data; /*< Location of section data. */
};
typedef struct RSectionHeaderT RSectionHeader;

/**
 * \brief Possible flags in the RSectionHeader.
 **/
#define R_SECTION_CODE    1  /* The bytecode. */
#define R_SECTION_SYMBOL  2  /* The symbol table. */
#define R_SECTION_DIRECTS 4  /* The direct values table*/
#define R_SECTION_START   8  /* (must be a bytecode section) This section
                              * starts the execution of the program. */
#define R_SECTION_DEPEND  16 /* Dependency list. */

/**
 * An explanation of the contents of the sections:
 *
 * CODE: Section is simply a sequence of RUnits.
 * SYMBOL: Section is a sequence of RSymbolHeaders.
 * DIRECTS: Section is a sequence of RDirectHeaders.
 * DEPEND: Section is a sequence of RDependHeaders.
 **/

struct RSymbolHeaderT {
  uint32_t p_symbol; /* Pointer to the symbol text (in UTF-8). */
};
typedef struct RSymbolHeaderT RSymbolHeader;

struct RDirectHeaderT {
  uint32_t flag; /*< What kind of a direct value is it? */
  uint32_t extra; /*< Extra information, if any. */
};
typedef struct RDirectHeaderT RDirectHeader;

struct RDependHeaderT {
  uint32_t flag; /*< What kind of a dependence? */
  uint32_t p_name; /*< Name depended upon. */
};
typedef struct RDependHeader;

/**
 * \brief Load and parse a file.
 * \param[in] data Contents of the file.
 * \param[in] size Length of the contents of the file.
 **/
void r_vmfile_load(void* data, uint32_t size);

#endif /* R_VMFILE_H */
